grammar MessagingGrammar;

// java -jar antlr-4.2-complete.jar Grammar.g4 -o generated

options {
  language = Java;
}

@header {
  package gatperdut.chato.core.messaging.grammar.generated;
  import gatperdut.chato.core.messaging.grammar.messinfo.MessageInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.ListRoomsInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.ListPlayersInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.ListItemTemplatesInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.ListItemsInRoomInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.CreateRoomInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.CreatePlayerInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.CreateItemTemplateInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.UpdateRoomsInfo;
  import gatperdut.chato.core.messaging.grammar.messinfo.UpdateItemsInfo;
} 

@members {
  	
  private MessageInfo mi;
  
}

command returns [MessageInfo messageInfo]
@after {
	 $messageInfo = mi;
}
	: 
	| list
	| create
	| update
	;

list
	: WS? LIST WS 
	( ROOMS
	{
		mi = new ListRoomsInfo();	
	}
	| PLAYERS
	{
		mi = new ListPlayersInfo();
	}
	| ITEM_TEMPLATES
	{
		mi = new ListItemTemplatesInfo();
	}
	| ITEMS_IN_ROOM WS roomID=NUMBER
	{
		mi = new ListItemsInRoomInfo( $roomID.text );
	}
	
	) WS?
	;

create
	: WS? CREATE WS
	( ROOMS
	{
		mi = new CreateRoomInfo();	
	}
	| PLAYERS WS? pd=json
	{
		mi = new CreatePlayerInfo( $pd.text );
	}
	| ITEM_TEMPLATES WS? pd=json
	{
		mi = new CreateItemTemplateInfo( $pd.text );
	}
	) WS?
	;

update
	: WS? UPDATE WS
	( ROOMS WS? rd=json
	{
		mi = new UpdateRoomsInfo( $rd.text );
	}
	| ITEMS WS? id=json
	{
		mi = new UpdateItemsInfo( $id.text );	
	}
	) WS?
	;

// JSON grammar definition.
json: object
| array
;
object
: '{' pair (',' pair)* '}'
| '{' '}' // empty object
;
pair: STRING ':' value ;
array
: '[' value (',' value)* ']'
| '[' ']' // empty array
;
value
: STRING
| NUMBER
| object // recursion
| array // recursion
| 'true' // keywords
| 'false'
| 'null'
;
STRING : '"' (ESC | ~["\\])* '"' ;
fragment ESC : '\\' (["\\/bfnrt] | UNICODE) ;
fragment UNICODE : 'u' HEX HEX HEX HEX ;
fragment HEX : [0-9a-fA-F] ;
NUMBER
: '-'? INT '.' [0-9]+ EXP? // 1.35, 1.35E-9, 0.3, -4.5
| '-'? INT EXP // 1e10 -3e4
| '-'? INT // -3, 45
;
fragment INT : '0' | [1-9] [0-9]* ; // no leading zeros
fragment EXP : [Ee] [+\-]? INT ; // \- since - means "range" inside [...]
// End JSON grammar definition.

LIST: 'list';
CREATE: 'create';
UPDATE: 'update';

ROOMS: 'rooms';
PLAYERS:'players';
ITEM_TEMPLATES: 'item_templates';
ITEMS: 'items';
ITEMS_IN_ROOM: 'items_in_room';

WS : (' ' | '\t')+;
